from selenium import webdriver
import time

# 创建一个浏览器实例
driver = webdriver.Chrome()
# driver_ie = webdriver.Ie()
# driver_firefox = webdriver.Firefox()

# 控制浏览器
# 浏览器类型
driver.name
# 最大化浏览器
driver.maximize_window()
# 最小化浏览器
driver.minimize_window()
# 打开网址
url = 'https://liushilive.github.io/html_example/'
driver.get(url)
# 标题
driver.title
# 当前网址
driver.current_url
# 获取页面源代码
with open(r'd:\1.html', 'w', encoding='utf-8') as f:
    f.write(driver.page_source)
# 截屏
driver.save_screenshot(r"d:\1.png")
# 网页刷新
driver.refresh()
# 网页后退
driver.back()
# 网页前进
driver.forward()

# 关闭标签页
driver.close()
# 关闭浏览器
driver.quit()

# 查找单个元素：find_element_by_
# id
ele = driver.find_element_by_id("uid")
# name
ele = driver.find_element_by_name("user")
# xpath
ele = driver.find_element_by_xpath("")
# link text
ele = driver.find_element_by_link_text("返回演示官网")
# partial link text
ele = driver.find_element_by_partial_link_text('演示')
# class name
ele = driver.find_element_by_class_name("A")
# tag name
ele = driver.find_element_by_tag_name("a")
# css selector
ele = driver.find_element_by_css_selector("#D1")

# 查找多个个元素：find_elements_by_
eles = driver.find_elements_by_tag_name("h2")
type(eles)
len(eles)

# 元素操作
ele = driver.find_element_by_id("uid")
ele.click()  # 点击
ele.tag_name  # tag名字
ele.text  # 文本值
ele.get_attribute("name")  # 获取属性值
ele.is_displayed()  # 是否可见
ele.is_enabled()  # 是否可使用
ele.is_selected()  # 是否被选择
ele.size  # 大小
ele.location  # 位置
ele.location_once_scrolled_into_view  # 返回可见位置

# 输入值
ele.send_keys('你好')
ele.send_keys('你好', '不好')
ele.send_keys(123456)
# 清空
ele.clear()
# 输入键盘按键
from selenium.webdriver.common.keys import Keys

ele.send_keys(Keys.LEFT * 2, Keys.BACK_SPACE)

# 下拉选框
ele = driver.find_element_by_id("s1Id")
ele.click()
ele_option = driver.find_element_by_xpath("//*[@value='sz']")
ele_option.click()
ele.click()

from selenium.webdriver.support.select import Select

# 单选
ele = driver.find_element_by_id("s1Id")
select = Select(ele)  # 创建一个下拉框对象
select.is_multiple  # 判断是否为多选框，单选返回Node，多选返回True
select.options  # 可选项目
select.select_by_index(0)  # 根据下标选择，从0开始
select.select_by_value("sz")  # 根据 value属性值选择
select.select_by_visible_text('北京')  # 根据显式的文本选择

# 多选
ele = driver.find_element_by_id("s3Id")
select = Select(ele)
select.is_multiple
select.select_by_index(0)
select.select_by_index(1)
select.select_by_index(2)
select.select_by_index(3)
select.select_by_index(4)
select.select_by_index(5)
select.select_by_index(6)
# 当前选择的项目
select.all_selected_options
# 取消选择，只适用于多选
select.deselect_by_index(1)
select.deselect_by_index(3)
select.deselect_by_index(5)
select.deselect_all()

# 警告框
driver.find_element_by_name("b1").click()
alert = driver.switch_to.alert  # 进入警告框，得到警告框对象
alert.text  # 文本
alert.accept()  # 点击确认
alert.dismiss()  # 点击取消

driver.find_element_by_name("b2").click()
alert = driver.switch_to.alert
alert.send_keys("我爱你")
alert.accept()

# 双击元素
ele = driver.find_element_by_xpath("//*[contains(text(), '请双击这里')]")
ac = webdriver.ActionChains(driver)  # 创建行动链对象
ac.double_click(ele)  # 定义双击元素的行为
ac.perform()  # 执行行动链

# 鼠标悬浮
ele = driver.find_element_by_link_text("分 类")
webdriver.ActionChains(driver).move_to_element(ele).perform()
ele = driver.find_element_by_link_text("编程语言")
webdriver.ActionChains(driver).move_to_element(ele).perform()
# 鼠标从当前位置为远点（0 , 0），移动一个偏移量
webdriver.ActionChains(driver).move_by_offset(100, 20).perform()

# 拖放
# 滑动验证码
# 查找滑动块
ele1 = driver.find_element_by_xpath('//*[@id="drag"]/div[3]')
# 查找滑动区域
ele2 = driver.find_element_by_xpath('//*[@id="drag"]/div[2]')
# 获取滑动区域的宽度
w = ele2.size.get("width")
# 一次性滑动
# webdriver.ActionChains(driver).drag_and_drop_by_offset(ele1, w, 0).perform()
# 在元素上按下左键
webdriver.ActionChains(driver).click_and_hold(ele1).perform()
for i in range(50):
    # 将鼠标移动一个偏移量
    webdriver.ActionChains(driver).move_by_offset(w / 50, 0).perform()
    time.sleep(0.1)
# 释放鼠标左键
webdriver.ActionChains(driver).release().perform()

# 查找元素
ele1 = driver.find_element_by_xpath('//*[@data-dad-id="1"]')
ele2 = driver.find_element_by_xpath('//*[@data-dad-id="2"]')
webdriver.ActionChains(driver).drag_and_drop(ele1, ele2).perform()

# JS 执行
scroll_top_js = "window.scrollTo(0,0);"  # 定义js脚本：滚动到页面顶部
scroll_end_js = "window.scrollTo(0,document.body.scrollHeight);"  # 定义js脚本：滚动到页面底部
scroll_view_js = "arguments[0].scrollIntoView();"  # 滚动到元素

driver.execute_script(scroll_top_js)
driver.execute_script(scroll_end_js)
ele = driver.find_element_by_name("b1")
driver.execute_script(scroll_view_js, ele)

# Cookies
# 添加
driver.add_cookie({'name': 'lisi', 'value': '12346'})
driver.add_cookie({'name': 'wangwu', 'value': '123'})
# 获取
driver.get_cookie('lisi')
# 获取所有
driver.get_cookies()
# 删除
driver.delete_cookie("lisi")
# 清空
driver.delete_all_cookies()

# frame
ele_frame = driver.find_element_by_name("frame1")
# 跳入框架
driver.switch_to.frame(ele_frame)
ele = driver.find_element_by_id("sb_form_q")
ele.send_keys("刘老师")
# 跳到父框架
driver.switch_to.parent_frame()
# 跳到默认框架
driver.switch_to.default_content()

# 标签页
# 通过判断标题
for handle in driver.window_handles:
    # driver.window_handles:返回会话中当前窗口的所有句柄
    if 'Bing' in driver.title:
        break
    driver.switch_to.window(handle)

# 通过判断 URL
for handle in driver.window_handles:
    # driver.window_handles:返回会话中当前窗口的所有句柄
    if 'liushilive' in driver.current_url:
        break
    driver.switch_to.window(handle)

# 等待
# 显式等待
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

driver.refresh()
ele = WebDriverWait(driver, 15).until(
    EC.presence_of_element_located((By.ID, 't1'))
)

# 智能等待
driver.implicitly_wait(15)

driver.refresh()
ele = driver.find_element_by_id("t1")
